package server;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import service.ExamService;
import service.ExamServiceImpl;
import dao.EntityContext;
import exception.BaseException;

/** 服务器端 */
public class ExamServiceServer {
	private EntityContext context;
	private Map<String, ExamService> serviceMap = new HashMap<String, ExamService>();

	public ExamServiceServer(EntityContext context) {
		this.context = context;
	}

	/**
	 * 启动服务器端的监听
	 * 
	 * @throws IOException
	 */
	public void listen() throws IOException {
		int port = context.getConfig().getInt("ServerPort");

		ServerSocket serverSocket = new ServerSocket(port);
		while (true) {
			System.out.println("服务器登陆");
			Socket socket = serverSocket.accept();
			new Service(socket).start();
		}
	}

	class Service extends Thread {
		Socket socket;

		public Service(Socket socket) {
			this.socket = socket;
		}

		@Override
		public void run() {
			try {
				ObjectOutputStream out = new ObjectOutputStream(socket
						.getOutputStream());
				ObjectInputStream in = new ObjectInputStream(socket
						.getInputStream());
				processRequest(in, out);
			} catch (IOException e) {
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (NoSuchMethodException e) {
				e.printStackTrace();
			}
		}
	}

	public static void main(String[] args) {

	}

	/**
	 * 获取客户端请求，根据请求调用业务逻辑的响应方法
	 * 
	 * @throws ClassNotFoundException
	 * @throws IOException
	 * @throws NoSuchMethodException
	 * @throws SecurityException
	 */
	public void processRequest(ObjectInputStream in, ObjectOutputStream out)
			throws IOException, ClassNotFoundException, SecurityException,
			NoSuchMethodException {
		Request request = (Request) in.readObject();
		String sessionId = request.getSessionId();
		if (sessionId == null) {
			sessionId = UUID.randomUUID().toString();
			ExamService service = new ExamServiceImpl(context);
			serviceMap.put(sessionId, service);
		}
		ExamService service = serviceMap.get(sessionId);
		Class cls = service.getClass();
		String methodName = request.getMethod();
		Class[] argsTypes = request.getArgsTypes();
		Object[] params = request.getArgs();
		Method method = cls.getDeclaredMethod(methodName, argsTypes);
		// 执行业务方法
		Response res;
		try {
			// 执行val = service.login(1001, "1234")
			Object val = method.invoke(service, request.getArgs());
			res = new Response(sessionId, val);
		} catch (InvocationTargetException e) {
			e.printStackTrace();
			BaseException ex = (BaseException) e.getTargetException();
			res = new Response(sessionId, ex);
		} catch (Exception e) {
			e.printStackTrace();
			res = new Response(sessionId, e);
		}
		out.writeObject(res);
		out.flush();
	}
}
